﻿#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN            // 从 Windows 头中排除极少使用的资料
#endif

#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // 某些 CString 构造函数将是显式的

// 关闭 MFC 对某些常见但经常可放心忽略的警告消息的隐藏
#define _AFX_ALL_WARNINGS

#include <afxwin.h>         // MFC 核心组件和标准组件
#include <afxext.h>         // MFC 扩展

#include <afxdisp.h>        // MFC 自动化类

#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h>           // MFC 对 Internet Explorer 4 公共控件的支持
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>                     // MFC 对 Windows 公共控件的支持
#endif // _AFX_NO_AFXCMN_SUPPORT

// 项目头文件
#include "DelayCamerDevice.h"
#include "DelayDevice.h"
#include <atlstr.h>

// 初始化静态成员变量
DelayCamerDevice* DelayCamerDevice::m_instance = nullptr;
CRITICAL_SECTION DelayCamerDevice::m_cs = {0}; // 初始化临界区结构体

/**
 * @brief DelayCamerDevice类的构造函数
 * @details 初始化临界区和回调函数指针
 */
DelayCamerDevice::DelayCamerDevice()
{
	// 初始化临界区
	InitializeCriticalSection(&m_cs);
}

/**
 * @brief DelayCamerDevice类的析构函数
 * @details 清理临界区资源
 */
DelayCamerDevice::~DelayCamerDevice()
{
	// 清理临界区
	DeleteCriticalSection(&m_cs);
}

/**
 * @brief 禁用拷贝构造函数
 * @details 防止类实例被拷贝
 */
DelayCamerDevice::DelayCamerDevice(const DelayCamerDevice&)
{
}

/**
 * @brief 禁用赋值运算符
 * @details 防止类实例被赋值
 * @return DelayCamerDevice引用
 */
DelayCamerDevice& DelayCamerDevice::operator=(const DelayCamerDevice&)
{
	return *this;
}

/**
 * @brief 获取DelayCamerDevice类的单例实例
 * @details 使用双重检查锁定模式确保线程安全
 * @return DelayCamerDevice类的单例指针
 */
DelayCamerDevice* DelayCamerDevice::GetInstance()
{
	// 第一次检查，避免不必要的临界区进入
	if (m_instance == nullptr)
	{
		// 进入临界区
		EnterCriticalSection(&m_cs);
		
		// 第二次检查，确保在等待临界区期间没有其他线程创建实例
		if (m_instance == nullptr)
		{
			m_instance = new DelayCamerDevice();
		}
		
		// 离开临界区
		LeaveCriticalSection(&m_cs);
	}
	
	return m_instance;
}

/**
 * @brief 设置设备连接回调函数
 * @param devConnFunc 设备连接回调函数指针
 */
void DelayCamerDevice::SetDevConnCallback(FunBakDevConn devConnFunc)
{
	// 设置原始DelayDevice的回调函数
	CDelayDevice::GetInstance()->BakDevConn = devConnFunc;
}

/**
 * @brief 设置设备状态回调函数
 * @param devStsFunc 设备状态回调函数指针
 */
void DelayCamerDevice::SetDevStsCallback(FunBakDevSts devStsFunc)
{
	// 设置原始DelayDevice的回调函数
	CDelayDevice::GetInstance()->BakDevSts = devStsFunc;
}

/**
 * @brief 设置校正状态回调函数
 * @param corrStsFunc 校正状态回调函数指针
 */
void DelayCamerDevice::SetCorrStsCallback(FunBakCorrSts corrStsFunc)
{
	// 设置原始DelayDevice的回调函数
	CDelayDevice::GetInstance()->BakCorrSts = corrStsFunc;
}

/**
 * @brief 设置Flash状态回调函数
 * @param flashStsFunc Flash状态回调函数指针
 */
void DelayCamerDevice::SetFlashStsCallback(FunBakFlashSts flashStsFunc)
{
	// 设置原始DelayDevice的回调函数
	CDelayDevice::GetInstance()->BakFlashSts = flashStsFunc;
}

/**
 * @brief 设置AD/IO回调函数
 * @param adIoFunc AD/IO回调函数指针
 */
void DelayCamerDevice::SetAdIoCallback(FunBakADIO adIoFunc)
{
	// 设置原始DelayDevice的回调函数
	CDelayDevice::GetInstance()->BakADIO = adIoFunc;
}

/**
 * @brief 设置IP状态回调函数
 * @param setIPStsFunc IP状态回调函数指针
 */
void DelayCamerDevice::SetIPStsCallback(FunBakSetIPSts setIPStsFunc)
{
	// 设置原始DelayDevice的回调函数
	CDelayDevice::GetInstance()->BakSetIPSts = setIPStsFunc;
}

/**
 * @brief 设置命令同步回调函数
 * @param cmdSameFunc 命令同步回调函数指针
 */
void DelayCamerDevice::SetCmdSameCallback(FunBakCmdSame cmdSameFunc)
{
	// 设置原始DelayDevice的回调函数
	CDelayDevice::GetInstance()->BakCmdSame = cmdSameFunc;
}

/**
 * @brief 获取设备IP信息（字符串格式）
 * @param ip 输出参数，设备IP地址
 * @param mask 输出参数，子网掩码
 * @param gate 输出参数，网关地址
 * @param port 输出参数，端口号
 */
void DelayCamerDevice::GetIpInfo(std::string& ip, std::string& mask, std::string& gate, int& port)
{
	CString cstrIp, cstrMask, cstrGate;
	CDelayDevice::GetInstance()->GetIpInfo(cstrIp, cstrMask, cstrGate, port);
	
	// 转换CString到std::string
	ip = CT2A(cstrIp);
	mask = CT2A(cstrMask);
	gate = CT2A(cstrGate);
}

/**
 * @brief 设置设备IP信息（字符串格式）
 * @param ip 设备IP地址
 * @param mask 子网掩码
 * @param gate 网关地址
 * @param port 端口号
 */
void DelayCamerDevice::SetIpInfo(const std::string& ip, const std::string& mask, const std::string& gate, int port)
{
	CString cstrIp(ip.c_str());
	CString cstrMask(mask.c_str());
	CString cstrGate(gate.c_str());
	CDelayDevice::GetInstance()->SetIpInfo(cstrIp, cstrMask, cstrGate, port);
}

/**
 * @brief 获取设备IP信息（整数格式）
 * @param ip 输出参数，设备IP地址（数组形式，4个整数）
 * @param mask 输出参数，子网掩码（数组形式，4个整数）
 * @param gate 输出参数，网关地址（数组形式，4个整数）
 * @param port 输出参数，端口号
 */
void DelayCamerDevice::GetIpInfo2(int* ip, int* mask, int* gate, int& port)
{
	CDelayDevice::GetInstance()->GetIpInfo2(ip, mask, gate, port);
}

/**
 * @brief 设置设备IP信息（整数格式）
 * @param ip 设备IP地址（数组形式，4个整数）
 * @param mask 子网掩码（数组形式，4个整数）
 * @param gate 网关地址（数组形式，4个整数）
 * @param port 端口号
 */
void DelayCamerDevice::SetIpInfo2(int* ip, int* mask, int* gate, int port)
{
	CDelayDevice::GetInstance()->SetIpInfo2(ip, mask, gate, port);
}

/**
 * @brief 检查TCP连接状态
 * @return TCP连接已打开返回true，否则返回false
 */
bool DelayCamerDevice::IsOpenTcp()
{
	return CDelayDevice::GetInstance()->IsOpenTcp();
}

/**
 * @brief 打开TCP连接
 * @return 成功返回0，失败返回错误码
 */
int DelayCamerDevice::OpenTcp()
{
	return CDelayDevice::GetInstance()->OpenTcp();
}

/**
 * @brief 关闭TCP连接
 * @return 成功返回0，失败返回错误码
 */
int DelayCamerDevice::CloseTcp()
{
	return CDelayDevice::GetInstance()->CloseTcp();
}

/**
 * @brief 获取设备状态
 * @return 成功返回0，失败返回错误码
 */
int DelayCamerDevice::GetDevSts()
{
	return CDelayDevice::GetInstance()->GetDevSts();
}

/**
 * @brief 设置校正参数
 * @return 成功返回0，失败返回错误码
 */
int DelayCamerDevice::SetCorrect()
{
	return CDelayDevice::GetInstance()->SetCorrect();
}

/**
 * @brief 获取上传信息
 * @param time 是否带时间戳
 * @return 成功返回0，失败返回错误码
 */
int DelayCamerDevice::GetUpInfo(bool time)
{
	return CDelayDevice::GetInstance()->GetUpInfo(time);
}

/**
 * @brief 设置Flash参数
 * @param inst Flash参数结构体指针
 * @return 成功返回0，失败返回错误码
 */
int DelayCamerDevice::SetFlash(str_Flash* inst)
{
	return CDelayDevice::GetInstance()->SetFlash(inst);
}

/**
 * @brief 设置延时参数
 * @param inst 延时参数结构体指针
 * @return 成功返回0，失败返回错误码
 */
int DelayCamerDevice::SetArgs(str_Args* inst)
{
	return CDelayDevice::GetInstance()->SetArgs(inst);
}

/**
 * @brief 设置设备IP
 * @param inst IP参数结构体指针
 * @return 成功返回0，失败返回错误码
 */
int DelayCamerDevice::SetIP(str_IP* inst)
{
	return CDelayDevice::GetInstance()->SetIP(inst);
}